package lesson4;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyCondition {

    private Queue queue;

    private int queueMax;

    private ReentrantLock lock = new ReentrantLock();

    private Condition empty = lock.newCondition();

    private Condition notFull = lock.newCondition();

    public MyCondition(Queue queue, int queueMax){
        this.queue = queue;
        this.queueMax = queueMax;
    }

    public void put(Object object) throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() == queueMax){
                System.out.println("query is full");
                notFull.await();
            }
            System.out.println("put queue size " + queue.size());
            queue.add(object);
            empty.signalAll();
        }finally {
            lock.unlock();
        }
    }

    public void take(){
        lock.lock();
        try {
            while (queue.size() == 0){
                System.out.println("query is empty ");
                empty.await();
            }
            System.out.println("take queue size " + queue.size());
            queue.remove();
            notFull.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        MyCondition myCondition = new MyCondition(new LinkedList(), 5);

        Runnable producer = () -> {
            try {
                while(true){
                    myCondition.put(new Object());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        Thread thread1 = new Thread(producer);
        //Thread thread2 = new Thread(producer);
        thread1.start();
        //thread2.start();

        Runnable consumer = () -> {
            while (true){
                myCondition.take();
            }
        };

        Thread thread3 = new Thread(consumer);
        //Thread thread4 = new Thread(consumer);
        thread3.start();
        //thread4.start();
    }
}
